using System;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Deepcode.Flux.Core.Services.FluxClient;


namespace Deepcode.Flux.Core.UI.Controls
{
	/// <summary>
	/// CollapseSection is a gradient strip that has a pulldown / pull up button. The child
	/// contents are shown/hidden as a result of expanding or collapsing the section. The
	/// section can optionally auto-postback when the it is expanded or collapsed.
	/// </summary>
	[
	ParseChildren(false),
	PersistChildren(true)
	]
	public class CollapseSection : Deepcode.Flux.Core.UI.Controls.Base.BaseControl, IPostBackEventHandler
	{
		#region Control Properties
		/// <summary>
		/// Specifies the header text for a heading / subheading panel
		/// </summary>
		[Category("Display"), Description("Specified the header text for the collapsable section")]
		public string Title
		{
			get
			{
				string s = (string) ViewState["Txt"];
				if( s == null ) return String.Empty;
				return s;
			}
			set
			{
				ViewState["Txt"] = value;
			}
		}
		/// <summary>
		/// Specifies whether the section is expanded or not - defaults to expanded (true)
		/// </summary>
		[Category("Display"), Description("Specifies if the section is expanded or not")]
		public bool Expanded
		{
			get
			{
				object exp = ViewState["exp"];
				if( exp == null ) return true;
				return (bool)exp;
			}
			set
			{
				ViewState["exp"] = value;
			}
		}
		/// <summary>
		/// Specifies whether or not the section should include the footer bar or not. (true by default)
		/// </summary>
		public bool WithFooter
		{
			get
			{
				object o = ViewState["foot"];
				if( o == null ) return true;
				return (bool) o;
			}
			set
			{
				ViewState["foot"] = value;
			}
		}
		/// <summary>
		/// Specifies a simple value to hold against this section as a unique identifier
		/// </summary>
		[Browsable(false)]
		public object Tag
		{
			get
			{
				return ViewState["tag"];
			}
			set
			{
				ViewState["tag"] = value;
			}
		}
		/// <summary>
		/// Set autopostback to true to force the section to perform a postback when a section
		/// is expanded or collapsed. Doing this allows you to then trap the OnToggle event
		/// </summary>
		[Category("Behaviour"), Description("Determines if the expand/collapse action performs a postback event or not")]
		public bool AutoPostback
		{
			get
			{
				object apb = ViewState["apb"];
				if( apb == null ) return false;
				return (bool) apb;
			}
			set
			{
				ViewState["apb"] = value;
			}
		}
		#endregion
		#region Rendering
		/// <summary>
		/// Renders the HTML for the tag opening
		/// </summary>
		/// <param name="writer"></param>
		public override void RenderBeginTag(System.Web.UI.HtmlTextWriter writer)
		{
			string RollupImage = ClientHelper.GetFluxClientFile("CollapseSection/Img/panelPullUp.jpg");
			string RolldownImage = ClientHelper.GetFluxClientFile("CollapseSection/Img/panelPullDown.jpg");
			string BackImage = ClientHelper.GetFluxClientFile("CollapseSection/Img/panelTile.jpg");

			string ControlDivID = this.ClientID + "_Area";
			string ControlImageID = this.ClientID + "_Img";
			string ControlHiddenField = this.ClientID + "hidden";
			
			string image = Expanded ? RollupImage : RolldownImage;

			string IMGTAG = String.Format("<img ID='{0}' NAME='{0}' src='{1}' align='absmiddle'/>", 
				ControlImageID, 
				Page.ResolveUrl(image));
			
			string OnClick = "";
			if( ! AutoPostback )
			{
				OnClick = String.Format(
					"CS_Toggle('{0}', '{1}', '{2}', '{3}', '{4}');", 
						ControlDivID, 
						ControlImageID, 
						ControlHiddenField,
						Page.ResolveUrl(RollupImage),
						Page.ResolveUrl(RolldownImage));
			}
			else
				OnClick = Page.ClientScript.GetPostBackEventReference(this, "ExpandCollapse");

			writer.Write("<DIV CLASS='CS_TITLEAREA' OnClick=\"{0}\">", OnClick);
			writer.Write("<table width='100%' cellspacing=0 cellpadding=0 border=0>");
			writer.Write("<tr>");
			writer.Write("<td width='100%' background='{1}' nowrap='nowrap' class='CS_TITLEAREA'>{0}</td>", this.Title, Page.ResolveUrl(BackImage));
			writer.Write("<td align=right background='{1}' class='CS_TITLEAREAIMAGE'>{0}</td>", IMGTAG, Page.ResolveUrl(BackImage));
			writer.Write("</tr></table></DIV>");

			string vis = "display:none;";
			if( Expanded ) vis = "display:inline;";
			writer.Write("<DIV ID='{0}' NAME='{0}' STYLE='{1}'>", ControlDivID, vis);
		}
		/// <summary>
		/// Renders the HTML for the closing tag
		/// </summary>
		/// <param name="writer"></param>
		public override void RenderEndTag(System.Web.UI.HtmlTextWriter writer)
		{
			if( this.WithFooter )
			{
				string FooterImage = ClientHelper.GetFluxClientFile("CollapseSection/Img/panelFooterTile.jpg");
				writer.Write("<table width='100%' height='5' cellspacing='0' cellpadding='0' border='0'>");
				writer.Write("<tr><td width='100%' height='5' background='{0}'><img src='{0}' width='10' height='5' alt='' border='0'/></td></tr>", FooterImage);
				writer.Write("</table>");
			}
			writer.Write("</DIV>");
		}
		#endregion
		#region Init / Setup
		/// <summary>
		/// Includes the stylesheets needed to render a panel
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			// Use the stylesheet for this control
			LoadClientStyleSheet("CollapseSection/CollapseSection.css", "Deepcode.Flux.Core.UI.Controls.CollapseSectionCSS");

			// Register a hidden field if we're not in auto-postback mode
			if( ! AutoPostback )
			{
				// Include the Javascript
				LoadClientScript("CollapseSection/CollapseSection.js", "Deepcode.Flux.Core.UI.Controls.CollapseSectionJS");

				string hiddenFieldName = this.ClientID + "hidden";
				// Have we posted back ?
				string hidden = Page.Request[hiddenFieldName];
				if( hidden != null )
				{
					// This is a postback, use value from hidden field
					if( hidden == "closed" ) Expanded = false;
					else Expanded=true;
				}
				else
				{
					// This is not a postback, set the hidden field to use my property value
					if( Expanded ) hidden="open";
					else hidden="closed";
				}
				Page.ClientScript.RegisterHiddenField( hiddenFieldName, hidden );
			}
		}
		#endregion
		#region IPostBackEventHandler Members
		public delegate void OnExpandCollapse( CollapseSection source );
		public event OnExpandCollapse ExpandCollapse;

		public void RaisePostBackEvent(string eventArgument)
		{
			if( eventArgument == "ExpandCollapse" )
			{
				this.Expanded = ! this.Expanded;
				if( ExpandCollapse != null ) ExpandCollapse( this );
				RaiseBubbleEvent( this, new CommandEventArgs("ExpandCollapse", this));
			}
		}
		#endregion
	}
}
